package com.zmn.oms.zmn.business.impl.work.autoflow.state;

import com.zmn.common.constant.FicoConsts;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.consts.GlobalConsts;
import com.zmn.oms.common.constant.ChannelConsts;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.constant.OrderPayConsts;
import com.zmn.oms.common.constant.OrderStatusConsts;
import com.zmn.oms.common.dro.orderpay.OrderPayResultDRO;
import com.zmn.oms.common.dto.ResultDTO;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.model.dto.work.masterwork.CompleteDTO;
import com.zmn.oms.model.dto.work.modify.must.ZsOrderPayDTO;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.services.interfaces.factory.OrderFactoryService;
import com.zmn.oms.services.interfaces.orderpay.AccountPayBService;
import com.zmn.oms.zmn.business.interfaces.work.ZsOrderWorkAmountBService;
import com.zmn.oms.zmn.business.interfaces.work.autoflow.state.WorkAutoFlowBService;
import com.zmn.oms.zmn.business.interfaces.work.orderpay.OrderPayResultBService;
import com.zmn.oms.zmn.business.interfaces.work.orderpay.ZsOrderPayBService;
import com.zmn.oms.zmn.normal.business.interfaces.work.masterwork.ZsNormalMasterWorkBService;
import com.zmn.pay.common.constant.PayConsts;
import com.zmn.pay.gateway.common.model.dro.PayGatewayDRO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Objects;

/**
 * @author sunlife
 * @date:2020/9/18 4:33 下午
 * description:
 */
@Slf4j
@Service("flowCompleteBService")
public class FlowCompleteBServiceImpl<T> implements WorkAutoFlowBService<T> {
	@Autowired
	ZsNormalMasterWorkBService zsNormalMasterWorkBService;
	@Autowired
	OrderFactoryService orderFactoryService;
	@Autowired
	ZsOrderPayBService zsOrderPayBService;
	@Autowired
	AccountPayBService accountPayBService;
	@Autowired
	ZsOrderWorkAmountBService zsOrderWorkAmountBService;
	@Autowired
	OrderPayResultBService orderPayResultBService;

	@Override
	public ResultDTO<T> condition(OrderWork orderWork) {
		if (orderWork.getStatus() >= OrderStatusConsts.WORK_STATUS_COMPLETE) {
			return ResultDTO.fail("工单已完成状态");
		}

		// 可以完成有两种情况：F端：服务完成&审核完毕  C端忽略，暂不考虑在这里做自动完成
		if (!(Objects.equals(orderWork.getBizType(), GlobalConsts.BIZ_TYPE_F)
				&& Objects.equals(orderWork.getStatus(), OrderStatusConsts.WORK_STATUS_SERVICE_COMPLETE)
				&& Objects.equals(orderWork.getResultStatus(), OrderStatusConsts.WORK_RESULT_DOING)
				&& Objects.equals(orderWork.getServiceCompleteReviewStatus(), OrderConsts.REVIEW_STATUS_SUCCESS))) {
			return ResultDTO.fail("工单不满足自动完成条件");
		}

		if (ChannelConsts.CHANNEL_ID_NOSUPPORT_ACCOUNT_PAY.contains(orderWork.getChannelId())) {
			if (NumberUtil.isNotNullOrZero(orderWork.getMasterAmount())) {
				return ResultDTO.fail("天猫渠道，有尾款，不满足自动完成");
			}
		} else {
			try {
				accountPayBService.checkAccount(orderWork.getOrderId(), orderWork.getMasterAmount());
			} catch (OmsBaseException e) {
				return ResultDTO.fail(e.getMessage());
			} catch (Exception e) {
				log.error(e.getMessage(), e);
				return ResultDTO.fail("检测余额异常");
			}
		}
		return ResultDTO.success(orderWork);
	}

	@Override
	public void execute(T t) {
		OrderWork orderWork = (OrderWork) t;

		// 支付
		if (Objects.equals(orderWork.getType(),OrderConsts.ORDER_TYPE_NEW)
				&& Objects.equals(com.zmn.consts.GlobalConsts.BIZ_TYPE_F, orderWork.getBizType())
				&& !ChannelConsts.CHANNEL_ID_NOSUPPORT_ACCOUNT_PAY.contains(orderWork.getChannelId())
				&& !Objects.equals(PayConsts.PAY_STATUS_DONE, orderWork.getPayStatus())) {
			ZsOrderPayDTO zsOrderPayDTO = new ZsOrderPayDTO();
			zsOrderPayDTO.setPayChannelId(accountPayBService.getPayChannelIdByOrderId(orderWork.getOrderId()));
			zsOrderPayDTO.setPayType(PayConsts.PAY_TYPE_INTO);
			zsOrderPayDTO.setTransferTime(new Date());
			zsOrderPayDTO.setSyncFlag(GlobalConsts.YES);
			zsOrderPayDTO.setOrderId(orderWork.getOrderId());
			zsOrderPayDTO.setWorkId(orderWork.getWorkId());
			zsOrderPayDTO.setPlat(orderWork.getPlatWork());
			zsOrderPayDTO.setOperatorPlat(orderWork.getPlatWork());
			zsOrderPayDTO.setOperator(com.zmn.common.constant.GlobalConsts.getOperatorTypeName(com.zmn.common.constant.GlobalConsts.OPERATE_USER_TYPE_SYSTEM));
			zsOrderPayDTO.setOperatorId(Long.valueOf(com.zmn.consts.GlobalConsts.OPERATE_USER_TYPE_SYSTEM));
			zsOrderPayDTO.setOperatorType(com.zmn.common.constant.GlobalConsts.OPERATE_USER_TYPE_SYSTEM);
			zsOrderPayDTO.setAccountType(FicoConsts.ACC_FACTORY);
			try {
				// 同步支付
				PayGatewayDRO payGatewayDRO = zsOrderPayBService.payMasterAmount(zsOrderPayDTO);

				// 更新支付结果
				OrderPayResultDRO orderPayResultDRO = orderPayResultBService.convertOrderPayResult(payGatewayDRO.getStatus());
				orderPayResultDRO.setAmountType(OrderPayConsts.ORDER_PAY_MASTER);
				// 更新工程师收款支付状态
				zsOrderWorkAmountBService.updateMasterAmountPayResult(orderPayResultDRO);
			} catch (OmsBaseException e) {
				log.error("自动完成--自动扣款失败===>{}", e.getMessage());
				return;
			} catch (Exception e) {
				log.error(e.getMessage(), e);
				return;
			}
		}

		// 完成
		try {
			CompleteDTO completeDTO = new CompleteDTO();
			completeDTO.setOrderId(orderWork.getOrderId());
			completeDTO.setWorkId(orderWork.getWorkId());
			completeDTO.setCompleteOnSite(GlobalConsts.YES);
			completeDTO.setOperator(com.zmn.common.constant.GlobalConsts.getOperatorTypeName(com.zmn.common.constant.GlobalConsts.OPERATE_USER_TYPE_SYSTEM));
			completeDTO.setOperatorId(Long.valueOf(com.zmn.consts.GlobalConsts.OPERATE_USER_TYPE_SYSTEM));
			completeDTO.setOperatorType(com.zmn.common.constant.GlobalConsts.OPERATE_USER_TYPE_SYSTEM);
			zsNormalMasterWorkBService.completeOrder(completeDTO);
		} catch (Exception e) {
			log.error("自动完成--失败===>{}", e.getMessage());
			log.error(e.getMessage(), e);
		}
	}

	private Integer getPayChannelIdBySettType(Integer settType) {
		Integer payChannelId = null;
		if (Objects.equals(FicoConsts.FACTORY_ACCOUNT_TYPE_PRECHARGE, settType)) {
			payChannelId = PayConsts.PAY_CHANNEL_PLATFORM_BALANCEAMOUNT;
		}
		// 后结算-授信支付
		else if (Objects.equals(FicoConsts.FACTORY_ACCOUNT_TYPE_SETTLEMENT, settType)) {
			payChannelId = PayConsts.PAY_CHANNEL_PLATFORM_CREDIT;
		} else {
			log.error("[{}]未知结算类型", settType);
		}
		return payChannelId;
	}

}
